﻿using System;
using System.Collections.Generic;
using System.Text;

namespace CartoLab.GeometryLib.Geometries
{
    public class CoordinateTransform
    {
        /// <summary>
        /// 把大地坐标转换为经纬度坐标，返回“弧度”单位
        /// </summary>
        /// <param name="X"></param>
        /// <param name="Y"></param>
        /// <param name="B">纬度(单位为弧度)</param>
        /// <param name="L">经度（单位为弧度）</param>
        static public void distance_XYtoBLAsRadian(double X, double Y, ref double B, ref double L)
        {
            double r = 6378140 * Math.Cos(Math.PI / 6) / Math.Sqrt(1.00 - Math.Pow(0.0818192215, 2) * Math.Pow(Math.Sin(Math.PI / 6), 2));
            B = Y / r;
            L = X / r;
        }

        /// <summary>
        /// 把大地坐标的X转换为经度坐标，返回“弧度”单位
        /// </summary>
        /// <param name="X"></param>
        /// <returns>经度(单位为弧度)</returns>
        static public double distance_XtoLAsRadian(double X)
        {
            double r = 6378140 * Math.Cos(Math.PI / 6) / Math.Sqrt(1.00 - Math.Pow(0.0818192215, 2) * Math.Pow(Math.Sin(Math.PI / 6), 2));
            double L = X / r;

            return L;
        }

        /// <summary>
        /// 把大地坐标的Y转换为纬度坐标，返回“弧度”单位
        /// </summary>
        /// <param name="X"></param>
        /// <returns>纬度(单位为弧度)</returns>
        static public double distance_YtoBAsRadian(double Y)
        {
            double r = 6378140 * Math.Cos(Math.PI / 6) / Math.Sqrt(1.00 - Math.Pow(0.0818192215, 2) * Math.Pow(Math.Sin(Math.PI / 6), 2));
            double B = Y / r;

            return B;
        }

        /// <summary>
        /// 把大地坐标X转换为经度坐标，返回“角度”单位
        /// </summary>
        /// <param name="X"></param>
        /// <returns>经度(单位为角度)</returns>
        static public double distance_XtoLAsAngle(double X)
        {
            double L = CoordinateTransform.distance_XtoLAsRadian(X);

            L *= 180 / Math.PI;

            return L;
        }

        /// <summary>
        /// 把大地坐标Y转换为纬度坐标，返回“角度”单位
        /// </summary>
        /// <param name="Y"></param>
        /// <returns>纬度(单位为角度)</returns>
        static public double distance_YtoBAsAngle(double Y)
        {
            double B = CoordinateTransform.distance_YtoBAsRadian(Y);

            B *= 180 / Math.PI;

            return B;
        }

        /// <summary>
        /// 把大地坐标转换为经纬度坐标，返回“角度”单位
        /// </summary>
        /// <param name="X"></param>
        /// <param name="Y"></param>
        /// <param name="B">纬度(单位为角度)</param>
        /// <param name="L">经度（单位为角度）</param>
        static public void distance_XYtoBLAsAngle(double X, double Y, ref double B, ref double L)
        {
            CoordinateTransform.distance_XYtoBLAsRadian(X, Y, ref B, ref L);

            B *= 180 / Math.PI;
            L *= 180 / Math.PI;
        }

        #region 把经纬度坐标转换成墨卡托投影坐标 modified by fish 2011.11.03 21:03
        /// <summary>
        /// 把经纬度坐标转换成墨卡托投影坐标
        /// 公式是小黄（黄青松）提供的！真是太感谢了！
        /// </summary>
        /// <param name="L">经度（单位是°）</param>
        /// <param name="B">纬度（单位是°）</param>
        /// <returns></returns>
        static public CartoLab.GeometryLib.Geometries.Coordinate Mercator_BLtoXY(double L, double B)
        {
            //    B *= Math.PI / 180;
            //    L *= Math.PI / 180;

            //    double Y = L * 6378140;
            //    double s = Math.Sqrt((1.0 - 0.0818192215 * Math.Sin(B)) / (1.0 + 0.0818192215 * Math.Sin(B)));
            //    double w1 = Math.Tan(Math.PI / 4.0 + B / 2.0);
            //    double w2 = Math.Pow(s, 0.0818192215 / 2);
            //    double w3 = Math.Log(w1 * w2);
            //    double X = 6378140 * w3;
            //    return new cartoGeometry.Coordinate(Y, X);
            B *= Math.PI / 180;
            L *= Math.PI / 180;
            double r = 6378140 * Math.Cos(Math.PI / 6) / Math.Sqrt(1.00 - Math.Pow(0.0818192215, 2) * Math.Pow(Math.Sin(Math.PI / 6), 2));
            double X = r * B;
            double Y = r * L;
            return new CartoLab.GeometryLib.Geometries.Coordinate(Y, X);
        }
        #endregion
    }
}
